Program debugging is an integral part of thorough software development. In the software development context, a "bug" is a program malfunction caused by a programming or logic error. A minor bug, such as a cursor that does not behave as expected, can be inconvenient or frustrating, even though it may not be damaging to information. More severe bugs can cause a program to stop responding to commands and might leave the user with no alternative but to restart the program. It is sometimes even necessary to reboot the computer to recover. Either of these alternatives might result in the loss of any work not already transferred to non-volatile data storage.
Because of the potential risk to important data, as well as the inconvenience and aggravation caused by program or system bugs, commercial application programs are tested and debugged as completely as possible before release. Such debugging requires not only identifying bugs by their symptoms, but also finding and correcting the programming errors that caused the bugs.
Various debugging systems have been developed for aiding programmers in finding sources of identified bugs. Some such debugging systems are hardware-based, requiring external connections to a target computer or microprocessor. However, software-based debugging systems are also effective, especially when working with reliable computer hardware which has already been thoroughly tested.
The rising complexity of microprocessors and operating systems has allowed debugging software to provide more capabilities than were previously possible. Modern multi-tasking computers and operating systems typically preclude or at least greatly reduce the possibility of an application program altering any program memory except its own. Thus, it is usually very difficult for a program to interfere with correct operation of other application programs or of the operating system itself. Accordingly, it is quite common to run a debugging program simultaneously with an application program which is to be debugged (a target program). When the operating system detects an error in the target program, the operating system can suspend the target program and pass control to the debugging program. The debugging program can then access memory locations, microprocessor registers, program counters, and other data to aid the programmer in finding the source of the error. The programmer can sometimes attempt on-the-fly fixes, and restart or single-step the program from the point where the error occurred.
One shortcoming of many debugging programs is that they must be loaded in program memory and running before the target program error occurs. This might be undesirable in many cases simply because of the system resources consumed by the debugging program. Furthermore, the presence of the debugging program in program memory, and the related consumption of resources, might have an effect on the target program, precluding effective debugging. More fundamentally, the programmer might simply have forgotten to initiate the debugging program. This shortcoming has been addressed in some operating systems such as Microsoft.RTM. Windows NT.TM.. The Windows NT.TM. operating system has a mechanism referred to as "exception handling." When an exception occurs, for example a general protection fault or a page fault, the running application program is notified and given the opportunity to self-correct. This is called "first chance exception handling." If the application program cannot handle or correct the exception, the operating system attempts to handle it in a procedure called "last chance exception handling." If this is also unsuccessful, the Windows NT.TM. operating system has a built-in mechanism for starting a utility program which can " connect" to the errant application and extract information about the program in its faulty state before terminating it.
There are programs which make use of this built-in mechanism. For instance, a program called DRWATSN32.EXE is supplied with the Windows NT.TM. operating system. DRWATSN32.EXE generates a human readable ASCII file with various static information relating to state of the application program at the time of the exception. Also, there are development environments which operate with the Windows NT.TM. operating system to load, start, and initialize a debugging program to debug the application program, in response to an application program error, without terminating the application program. This latter tactic is much more flexible, since it gives a programmer the opportunity to interactively explore various data storage areas used by the application program and in some cases to restart the application program.
Unfortunately, the Windows.RTM. 3.1 operating system is not able to load and run a debugging program in response to a program error. Generally, the Windows.RTM. 3.1 operating system will simply terminate an application in response to a generated exception. The Windows.RTM. 3.1 operating system does, however, have facilities for passing control to a debugging program which is already loaded and running. Such facilities are provided in the operating system itself, and are accessed through a library of Windows.RTM. 3.1 functions and data structures called the Tool Helper library. The Tool Helper library ships with the Microsoft.RTM. Windows.RTM. Software Development Kit (SDK) version 3.1 (Tool Helper is contained within three files: a dynamic-link library TOOLHELP.DLL, an import library TOOLHELP. LIB, and an include file TOOLHELP.H). Tool Helper functions can also run under the Windows.RTM. 3.0 operating system.
The Tool Helper library includes functions which enable a programmer to trap certain system interrupts. Specifically, the Tool Helper library allows trapping the following interrupts:
______________________________________ Name Number Meaning ______________________________________ INT.sub.-- DIV0 0 Divide-error Exception INT.sub.-- 1 1 Debugger interrupt INT.sub.-- 3 3 Breakpoint interrupt INT.sub.-- UDINSTR 6 Invalid-opcode exception INT.sub.-- STKFAULT 12 Stack Exception INT.sub.-- GPFAULT 13 General protection violation INT.sub.-- BADPAGEFAULT 14 Page fault not caused by normal virtual-memory operation INT-CTLALTSYSRQ 256 User pressed CTRL+ALT+SYSRQ ______________________________________
Using the Tool Helper functions, a debugging program can be registered with the operating system to receive notifications when these interrupts occur. To register for such notifications, the debugging program calls a Tool Helper function called InterruptRegister(), and supplies an argument consisting of a pointer to an interrupt callback function within the debugging program. The interrupt callback function is the debugger function which will handle interrupts. The operating system calls this function whenever one of the above interrupts occurs, and supplies an argument equal to the "number" of the interrupt.
It is possible for a number of different programs to register callback functions. Each interrupt callback function has the option of either handling the interrupt or passing it on to the next-registered callback function. Whether or not the exception has been handled is indicated by the response of the callback function. The operating system calls the registered callback functions in sequence until one of the callback functions resolves the interrupt. When an interrupt-handling routine is registered, it will be called for an exception generated by any program. A debugging program would choose to ignore an exception when, for example, it was generated by a program other than the program being debugged.
There are utility programs other than interactive debuggers which utilize the Tool Helper library to provide limited debugging information after system interrupts. These utilities typically operate similarly to the DRWATSN32.EXE program described above, providing varying degrees of static information about a program's state at the time of the system exception. To utilize the callback functions discussed above, however, these utilities must be running before interrupts occur. Furthermore, these utilities do not avoid termination of the faulting program. They do not make it possible for a programmer to interactively explore a program's data, register, and program storage areas as would be possible when running an interactive debugger such as Microsoft.RTM. CodeView.RTM. for Windows.RTM., for example.
The ability to automatically invoke a debugging program after a program error has occurred would be extremely helpful to Windows.RTM. 3.1 developers. Such a feature would significantly decrease the time required to test new programs or modules. Since the Windows.RTM. 3.1 operating system is currently used by a very significant part of the personal computer market, having such a feature would be beneficial to thousands of software developers.
The invention described and claimed below allows an application program to be tested without a debugging program being previously launched. When debugging is needed, the debugging program is automatically installed, subject to the approval of the programmer, without terminating the application program. The debugging program is initialized to debug the active application program, with all program information still available and accessible. When using a debugging program such as CodeView.RTM. for Windows.RTM., the programmer can interactively examine and alter data, and can also re-start or single-step through portions of the program as desired. This is a significant improvement over previous debugging methods under the Windows.RTM. 3.1 operating system which require a debugging program to be in memory and running prior to any program errors.